﻿using UnityEngine;
using UnityEngine.UI;
using System.Collections;

namespace ZXthex.CodingUI
{
    public class SelectDropdown : BaseCodingUI
    {
        private VerticalScrollArea vsa;
        private Image arrowBox;
        private Image arrow;

        private float m_dropMaxSize = 120;

        public float dropMaxSize
        {
            get { return m_dropMaxSize; }
            set
            {
                if (value < 30) return;

                m_dropMaxSize = value;
            }
        }

        public Dropdown dropdown { get; private set; }

        SelectDropdown() { }

        float ResizeViewport()
        {
            var height = (vsa.templateItem.layout.preferredHeight)+2;
            height = Mathf.Abs(height);
            height *= dropdown.options.Count;

            if (height > dropMaxSize)
            {
                height = dropMaxSize;
            }
            var r = vsa.scrollRect.transform as RectTransform;
            var sd = r.sizeDelta;
            sd.y = height;
            r.sizeDelta = sd;
            return height;
        }

        void ResizeViewportAndTempList()
        {
            var h = ResizeViewport();
            var listrt = dropdown.transform.GetChild(3) as RectTransform;
            var sd = listrt.sizeDelta;
            sd.y = h;
            listrt.sizeDelta = sd;
        }

        void RegisterCallbacks()
        {
            dropdown.GetComponent<Image>().RegisterDirtyLayoutCallback(ResizeUI);

            RegisterOnTransformAndChildCountChanged(dropdown, (delta) =>
            {
                if (delta > 0)
                {
                    ResizeViewportAndTempList();
                }
            });
        }

        void ResizeUI()
        {
            var rt = (dropdown.transform as RectTransform);
            const float h_max = 36f;
            const float h_min = 24f;
            if (rt.rect.height > h_max)
            {
                arrowBox.rectTransform.sizeDelta = new Vector2(arrowBox.rectTransform.rect.height*30f/ h_max, 0);
                arrow.rectTransform.localScale = Vector3.one;
                arrow.rectTransform.sizeDelta = new Vector2(20,10) * Mathf.Clamp(arrowBox.rectTransform.rect.height/ h_max, 1,1.5f);

            }
            else if (rt.rect.height < h_min)
            {
                arrowBox.rectTransform.sizeDelta = new Vector2(arrowBox.rectTransform.rect.height*30f/ h_min, 0);
                arrow.transform.localScale = Vector3.one * arrowBox.rectTransform.rect.height / h_min;
                arrow.rectTransform.sizeDelta = new Vector2(20, 10);
            }
            else
            {
                arrow.transform.localScale = Vector3.one;
                arrow.rectTransform.sizeDelta = new Vector2(20, 10);
            }

            dropdown.captionText.fontSize = UIHelper.GetRecommandFontSizeWithHeight((int)rt.rect.height);

            vsa.templateItem.layout.preferredHeight = rt.rect.height + 2;
            vsa.templateItem.childText.fontSize = UIHelper.GetRecommandFontSizeWithHeight((int)rt.rect.height);
            ResizeViewport();
        }

        public static SelectDropdown Instantiate(Transform parent = null)
        {
            var img = new GameObject("Select Dropdown", typeof(RectTransform)).AddComponent<Image>();
            img.sprite = CodingPool.GetSquare();
            img.type = Image.Type.Sliced;
            img.transform.SetParent(parent);
            
            Dropdown dd = img.gameObject.AddComponent<Dropdown>();

            Text label = CreateTextGameObject();
            label.name = "Label";
            dd.captionText = label;
            label.transform.SetParent(dd.transform);
            label.transform.localScale = Vector3.one;

            label.fontSize = UIHelper.GetRecommandFontSizeWithHeight(30);
            label.alignment = TextAnchor.MiddleLeft;

            Image arrowBox = new GameObject("Arrow Box", typeof(RectTransform)).AddComponent<Image>();
            arrowBox.transform.SetParent(dd.transform);
            arrowBox.sprite = CodingPool.GetDropdownSquare(2);
            arrowBox.type = Image.Type.Sliced;

            dd.targetGraphic = arrowBox;
            dd.transition = Selectable.Transition.SpriteSwap;
           
            var ss = dd.spriteState;
            ss.highlightedSprite = ss.pressedSprite = CodingPool.GetDropdownHighlightSquare(2);
            dd.spriteState = ss;

            Image arrow = new GameObject("Arrow", typeof(RectTransform)).AddComponent<Image>();
            arrow.transform.SetParent(arrowBox.transform);
            arrow.sprite = CodingPool.GetArrow(2);


            SetDefaultRectTransform(dd.transform as RectTransform);

            label.rectTransform.sizeDelta = new Vector2(-4,-4);

            arrowBox.rectTransform.anchorMin = Vector2.right;
            arrowBox.rectTransform.sizeDelta = new Vector2(arrowBox.rectTransform.rect.height, 0);
            arrowBox.rectTransform.pivot = new Vector2(1, 0.5f);
            arrowBox.rectTransform.anchoredPosition = new Vector2();

            arrow.transform.localScale = Vector3.one;
            arrow.rectTransform.anchoredPosition = new Vector2();
            arrow.rectTransform.sizeDelta = new Vector2(20, 10);

            var vsa = VerticalScrollArea.Instantiate(dd.transform, 32);
            var sr = vsa.scrollRect;
            sr.name = "Template";
            var srr = (sr.transform as RectTransform);
            srr.pivot = new Vector2(0.5f, 1.0f);
            srr.anchorMin = new Vector2();
            srr.anchorMax = new Vector2(1, 0);
            srr.anchoredPosition = new Vector2();
            var sd = srr.sizeDelta;
            sd.x = 0;
            srr.sizeDelta = sd;


            sr.gameObject.SetActive(false);

            dd.template = sr.transform as RectTransform;
            dd.itemText = vsa.templateItem.childText;
            dd.itemText.alignment = TextAnchor.MiddleLeft;

            vsa.templateItem.toggle.gameObject.SetActive(true);
            vsa.templateItem.toggle.group = null;
            vsa.templateItem.toggle.graphic.color = Color.clear;
            

            var sdd =  new SelectDropdown { dropdown = dd, vsa=vsa, arrowBox = arrowBox, arrow = arrow};

            sdd.RegisterCallbacks();

            return sdd;

        }

    }
}